<?php

namespace service\impl;

use service\exception\ServiceException;
use service\ext\PageData;
use service\service\UserCollectService;
use service\vo\user\UserCollect;
use think\db\exception\DbException;

class UserCollectServiceImpl extends BaseImpl implements UserCollectService
{
    //当前模块名称
    private static string $modeName = 'userCollect';

    /**
     * @inheritDoc
     */
    public function addUserCollect(UserCollect $userCollect): int
    {
        // TODO: Implement addUserCollect() method.
        $data = [
            self::$FIELD_COMMON_U_ID => $userCollect->getUserId(),
            self::$FIELD_COMMON_SUBJECT_ID => $userCollect->getSubjectId(),
            self::$FIELD_USER_COLLECT_ADD_TIME => date("Y-m-d H:i:s"),
        ];
        return $this->getUserCollectDb()->insert($data);
    }

    /**
     * @inheritDoc
     */
    public function addUserCollects(array $userCollects): int
    {
        // TODO: Implement addUserCollects() method.
        $data = [];
        foreach ($userCollects as $userCollect) {
            $data[] = [
                self::$FIELD_COMMON_U_ID => $userCollect->getUserId(),
                self::$FIELD_COMMON_SUBJECT_ID => $userCollect->getSubjectId(),
                self::$FIELD_USER_COLLECT_ADD_TIME => date("Y-m-d H:i:s")
            ];
        }
        return $this->getUserCollectDb()->insertAll($data);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserCollect(int $id): int
    {
        // TODO: Implement deleteUserCollect() method.
        return $this->getUserCollectDb()->delete($id);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserCollects(array $ids): int
    {
        // TODO: Implement deleteUserCollects() method.
        return $this->getUserCollectDb()->delete($ids);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserCollectByUserId(int $userId): int
    {
        // TODO: Implement deleteUserCollectByUserId() method.
        return $this->getUserCollectDb()
            ->where([self::$FIELD_COMMON_U_ID => $userId])
            ->delete();
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserCollectByUserIds(array $userIds): int
    {
        // TODO: Implement deleteUserCollectByUserIds() method.
        return $this->getUserCollectDb()
            ->whereIn(self::$FIELD_COMMON_U_ID, $userIds)
            ->delete();
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function deleteUserCollectBySubjectId(int $subjectId): int
    {
        // TODO: Implement deleteUserCollectBySubjectId() method.
        return $this->getUserCollectDb()
            ->where(self::$FIELD_COMMON_SUBJECT_ID, $subjectId)
            ->delete();
    }

    /**
     * @inheritDoc
     */
    public function getUserCollectById(int $id): UserCollect
    {
        // TODO: Implement getUserCollectById() method.
        $po = $this->getUserCollectDb()
            ->where(self::$FIELD_COMMON_ID, $id)
            ->findOrEmpty();
        if ($po->isEmpty()) {
            throw new ServiceException(self::$modeName, self::ERROR_USER_COLLECT_NOT_EXISTS);
        }

        return $this->getUserCollectVoFromPo($po);
    }

    /**
     * @inheritDoc
     * @throws DbException
     */
    public function getUserCollectByIds(array $ids): array
    {
        // TODO: Implement getUserCollectByIds() method.
        $voArr = [];
        $poArr = $this->getUserCollectDb()
            ->whereIn(self::$FIELD_COMMON_ID, $ids)
            ->select();
        foreach ($poArr as $po) {
            $voArr[] = $this->getUserCollectVoFromPo($po);
        }
        return $voArr;
    }

    /**
     * @inheritDoc
     *
     * @throws DbException
     */
    public function searchUserCollects(int $currentPage, int $pageSize, array $filterCriteria, array $sorterCriteria): PageData
    {
        // TODO: Implement searchUserCollects() method.
        // TODO: Implement searchSubjects() method.
        $filter = [];
        if (!empty($filterCriteria)) {
            foreach ($filterCriteria as $key => $value) {
                if (strcasecmp($key, self::$FILTER_USER_ID) == 0) {
                    //用户id
                    $filter[] = [self::$FIELD_COMMON_U_ID, "=", $value];
                } else if (strcasecmp($key, self::$FILTER_SUBJECT_ID) == 0) {
                    //题目id
                    $filter[] = [self::$FIELD_COMMON_SUBJECT_ID, "=", $value];
                } elseif (strcasecmp($key, self::$FILTER_ADD_TIME) == 0) {
                    //时间
                    $betweenTime = makeBetween($value['start'], $value['end']);
                    $filter[] = [self::$FIELD_USER_COLLECT_ADD_TIME, $betweenTime[0], $betweenTime[1]];
                }
            }
        }

        //构建排序条件
        $sort = [];
        if (!empty($sorterCriteria)) {
            foreach ($sorterCriteria as $key => $value) {
                if (strcasecmp($key, self::$SORT_ID) == 0) {
                    $sort[self::$FIELD_COMMON_ID] = $value ? self::$SORT_VALUE_ASC : self::$SORT_VALUE_DESC;
                }
            }
        }

        $count = $this->getPracticeDb()
            ->where($filter)
            ->count();
        $list = $this->getPracticeDb()
            ->where($filter)
            ->order($sort)
            ->limit($pageSize)
            ->page($currentPage)
            ->select();


        $dataList = [];
        foreach ($list as $po) {
            $dataList[] = $this->getUserCollectVoFromPo($po);
        }

        $pageData = new PageData();
        $pageData->setData($dataList);
        $pageData->setCount($count);

        return $pageData;
    }

    /**
     * @throws DbException
     */
    public function deleteUserCollectBySubjectIds(array $subjectIds): int
    {
        // TODO: Implement deleteUserCollectBySubjectIds() method.
        return $this->getUserCollectDb()
            ->whereIn(self::$FIELD_COMMON_SUBJECT_ID, $subjectIds)
            ->delete();
    }

    private function getUserCollectVoFromPo($po): UserCollect
    {
        $userCollect = new UserCollect();
        $userCollect->setUserId($po[self::$FIELD_COMMON_U_ID]);
        $userCollect->setSubjectId($po[self::$FIELD_COMMON_SUBJECT_ID]);
        $userCollect->setId($po[self::$FIELD_COMMON_ID]);
        $userCollect->setAddTime($po[self::$FIELD_USER_COLLECT_ADD_TIME]);
        return $userCollect;
    }
}